Popular Searches
Popular Course Categories
Popular Courses

Sending GET and POST requests

Sending GET and POST requests

Flutter APIs & Networking

Sending GET and POST Requests in Flutter

GET and POST requests are two of the most commonly used HTTP methods in Flutter applications. A GET request is generally used to retrieve data from a server, while a POST request is generally used to send data to a server and create or process a resource.

Flutter applications can communicate with REST APIs and web services using the http package. The basic workflow is to create a request, send it to the server, receive an HTTP response, check the response status, decode the returned data, and update the UI.


1. What Are GET and POST Requests?

HTTP requests allow a Flutter application to communicate with a backend server or REST API.

Flutter App
    ↓
HTTP Request
    ↓
API / Server
    ↓
HTTP Response
    ↓
Flutter App

The two important requests covered in this topic are:

  • GET: Generally used to retrieve information from a server.
  • POST: Generally used to send information to a server and commonly create a new resource.

2. Understanding the HTTP Request-Response Cycle

Whenever a Flutter application communicates with an API, the application acts as an HTTP client. It sends a request to a server and waits for the server to return a response.

1. Flutter creates request
        ↓
2. URI identifies endpoint
        ↓
3. HTTP method selected
        ↓
4. Headers/body added if required
        ↓
5. Request sent to server
        ↓
6. Server processes request
        ↓
7. HTTP response returned
        ↓
8. Flutter checks status code
        ↓
9. Response body is decoded
        ↓
10. UI is updated

3. GET vs POST

Feature GET POST
Primary purpose Retrieve data Send or create data
Flutter method http.get() http.post()
Request body Usually not used Commonly used
Query parameters Commonly used Can be used
Typical response Requested resource/data Created or processed resource
Example Get a list of users Create a new user

4. Adding the HTTP Package

Before sending HTTP requests, add the http package to your Flutter project.

flutter pub add http

Import the package into the Dart file:

import 'package:http/http.dart' as http;

The http package provides convenient methods for making HTTP requests such as GET and POST.

5. Internet Permission for Android

Android applications that communicate with internet services need network access. The Android application manifest should contain the internet permission.

The permission is normally placed in:

android/app/src/main/AndroidManifest.xml

Example:

<uses-permission android:name="android.permission.INTERNET"/>

Place the permission in the appropriate Android manifest configuration used by the application.

6. Understanding Uri

Every HTTP request needs a URL or URI identifying the API endpoint.

final uri = Uri.parse(
  'https://jsonplaceholder.typicode.com/albums/1',
);

You can also use Uri.https() when constructing URLs programmatically.

final uri = Uri.https(
  'example.com',
  '/api/users',
);

Uri.https() is particularly useful when working with query parameters because it handles URL construction and encoding.

7. Parts of an API URL

An API URL can contain multiple components.

https://example.com/api/users?page=1&limit=10
Part Example Purpose
Scheme https Communication protocol
Host example.com Server domain
Path /api/users Identifies resource or endpoint
Query ?page=1&limit=10 Provides filtering or other parameters

8. Sending a GET Request

A GET request is used to retrieve data from an API.

The basic syntax is:

final response = await http.get(
  Uri.parse('https://example.com/api/data'),
);

The http.get() method returns a Future, so the request is normally used with await inside an asynchronous function.

9. Simple GET Request Example

import 'package:http/http.dart' as http;

Future<void> fetchData() async {
  final response = await http.get(
    Uri.parse(
      'https://jsonplaceholder.typicode.com/albums/1',
    ),
  );

  print(response.statusCode);
  print(response.body);
}

In this example:

  • http.get() sends the GET request.
  • await waits for the response.
  • response.statusCode contains the HTTP status code.
  • response.body contains the returned response data.

10. Understanding async and await

Network requests take time because the application communicates with a remote server. Dart uses asynchronous programming so the application can perform network operations without blocking normal execution.

Future<void> fetchUsers() async {
  final response = await http.get(
    Uri.parse('https://example.com/api/users'),
  );

  print(response.body);
}

The async keyword marks a function as asynchronous. The await keyword waits for a Future to complete before continuing the function.

11. Understanding http.Response

The response returned from an HTTP request contains information received from the server.

Important properties include:

  • response.statusCode – HTTP status code.
  • response.body – response content.
  • response.headers – response headers.
final response = await http.get(
  Uri.parse('https://example.com/api/users'),
);

print(response.statusCode);
print(response.body);
print(response.headers);

12. Understanding HTTP Status Codes

The HTTP status code helps the application understand how the server handled the request.

Status Code Meaning Common Context
200 OK Successful request
201 Created Resource successfully created
400 Bad Request Invalid request data
401 Unauthorized Authentication required or invalid
403 Forbidden Server refuses access
404 Not Found Resource or endpoint not found
500 Internal Server Error Server-side failure

13. Checking GET Response Status

Always check the HTTP status code before processing a response as successful.

if (response.statusCode == 200) {
  print('Data fetched successfully');
  print(response.body);
} else {
  print('Failed to fetch data');
}

A 200 response generally indicates that the GET request was successfully processed.


14. GET Request with JSON Response

Most REST APIs return structured data in JSON format.

Example response:

{
  "id": 1,
  "title": "Flutter Course",
  "completed": false
}

Import the JSON library:

import 'dart:convert';

Decode the response:

final data = jsonDecode(response.body);

print(data['id']);
print(data['title']);
print(data['completed']);

After decoding, a JSON object can commonly be represented as a Dart Map, while a JSON array can be represented as a Dart List.

15. Understanding JSON Objects and Lists

APIs commonly return either a single JSON object or a list of JSON objects.

Single object:

{
  "id": 1,
  "name": "Rahul"
}

JSON array:

[
  {
    "id": 1,
    "name": "Rahul"
  },
  {
    "id": 2,
    "name": "Priya"
  }
]

In Dart:

final Map<String, dynamic> user = jsonDecode(response.body);

final List<dynamic> users = jsonDecode(response.body);

16. Creating a Model for GET Data

Instead of working with raw JSON throughout the application, create a Dart model class.

class Album {
  final int id;
  final String title;

  Album({
    required this.id,
    required this.title,
  });

  factory Album.fromJson(Map<String, dynamic> json) {
    return Album(
      id: json['id'],
      title: json['title'],
    );
  }
}

A model provides a structured representation of API data and makes application code easier to understand and maintain.

17. GET Request Returning a Model

Future<Album> fetchAlbum() async {
  final response = await http.get(
    Uri.parse(
      'https://jsonplaceholder.typicode.com/albums/1',
    ),
  );

  if (response.statusCode == 200) {
    final data = jsonDecode(response.body);
    return Album.fromJson(data);
  }

  throw Exception('Failed to load album');
}

This approach converts the API response into a strongly structured Dart object.

18. GET Request with Headers

Headers provide additional information to the server.

final response = await http.get(
  Uri.parse('https://example.com/api/users'),
  headers: {
    'Accept': 'application/json',
  },
);

Headers can be used for content negotiation, authentication, client information, and other API-specific requirements.

19. GET Request with Authorization Token

final response = await http.get(
  Uri.parse('https://example.com/api/profile'),
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'Accept': 'application/json',
  },
);

The exact authentication format depends on the API. Bearer tokens are one common approach for authenticated APIs.

Security note: Avoid hard-coding sensitive secrets or private credentials directly into client-side application code.

20. GET Request with Query Parameters

Query parameters are commonly used for searching, filtering, sorting, and pagination.

For example:

https://example.com/api/users?page=1&limit=10

In Dart, Uri.https() can be used:

final uri = Uri.https(
  'example.com',
  '/api/users',
  {
    'page': '1',
    'limit': '10',
  },
);

final response = await http.get(uri);

21. GET Request with Search

final uri = Uri.https(
  'example.com',
  '/api/products',
  {
    'search': 'laptop',
  },
);

final response = await http.get(uri);

The resulting request can represent a URL such as:

https://example.com/api/products?search=laptop

22. GET Request with Path Parameters

A path parameter is commonly used to identify a specific resource.

final userId = 10;

final response = await http.get(
  Uri.parse(
    'https://example.com/api/users/$userId',
  ),
);

For userId = 10, the endpoint becomes:

https://example.com/api/users/10

23. Handling GET Request Errors

Network operations can fail because of connectivity problems, server errors, invalid URLs, timeouts, or other exceptions. Use try-catch to handle exceptions.

Future<void> fetchData() async {
  try {
    final response = await http.get(
      Uri.parse('https://example.com/api/data'),
    );

    if (response.statusCode == 200) {
      print(response.body);
    } else {
      print('Server error: ${response.statusCode}');
    }
  } catch (e) {
    print('Network error: $e');
  }
}

24. GET Request with Timeout

A timeout prevents an application from waiting indefinitely for a server response.

Future<void> fetchData() async {
  try {
    final response = await http
        .get(
          Uri.parse('https://example.com/api/data'),
        )
        .timeout(
          const Duration(seconds: 10),
        );

    print(response.body);
  } catch (e) {
    print('Request failed: $e');
  }
}

25. Sending a POST Request

A POST request is commonly used to send data to a server and create a new resource.

The http package provides the http.post() method for this purpose.

Basic syntax:

final response = await http.post(
  Uri.parse('https://example.com/api/users'),
  body: {
    'name': 'Rahul',
    'email': '[email protected]',
  },
);

26. POST Request with JSON

Many REST APIs expect the request body to be JSON. Use jsonEncode() to convert Dart data into a JSON string.

import 'dart:convert';
import 'package:http/http.dart' as http;

Future<void> createUser() async {
  final response = await http.post(
    Uri.parse('https://example.com/api/users'),
    headers: {
      'Content-Type': 'application/json; charset=UTF-8',
    },
    body: jsonEncode({
      'name': 'Rahul',
      'email': '[email protected]',
    }),
  );

  print(response.statusCode);
  print(response.body);
}

When the API expects JSON, the request should normally specify an appropriate JSON Content-Type header.

27. Understanding Content-Type

The Content-Type header tells the server what type of data is contained in the request body.

For JSON:

headers: {
  'Content-Type': 'application/json; charset=UTF-8',
}

This is especially important when sending JSON data to REST APIs because the server needs to know how to interpret the request body.

28. POST Request with User Input

Flutter applications frequently collect information from TextField widgets and send it to an API.

final TextEditingController nameController =
    TextEditingController();

final TextEditingController emailController =
    TextEditingController();

Future<void> createUser() async {
  final response = await http.post(
    Uri.parse('https://example.com/api/users'),
    headers: {
      'Content-Type': 'application/json; charset=UTF-8',
    },
    body: jsonEncode({
      'name': nameController.text,
      'email': emailController.text,
    }),
  );

  if (response.statusCode == 201) {
    print('User created successfully');
  } else {
    print('Failed to create user');
  }
}

29. POST Request Using a Button

ElevatedButton(
  onPressed: () {
    createUser();
  },
  child: const Text('Create User'),
)

When the user presses the button, the application can collect the input and send it to the backend using a POST request.

30. Understanding HTTP 201 Created

When a POST request successfully creates a new resource, the server may return HTTP status code 201.

if (response.statusCode == 201) {
  print('Resource created');
} else {
  print('Failed to create resource');
}

The exact response status depends on the API contract, so the application should follow the status codes documented by the backend.

31. POST Response Parsing

A POST request may return the newly created resource in the response body.

Example response:

{
  "id": 101,
  "title": "Flutter Course"
}

Decode it:

final data = jsonDecode(response.body);

print(data['id']);
print(data['title']);

32. POST Response with a Model

class Product {
  final int id;
  final String name;

  Product({
    required this.id,
    required this.name,
  });

  factory Product.fromJson(Map<String, dynamic> json) {
    return Product(
      id: json['id'],
      name: json['name'],
    );
  }
}

Use the model after receiving the response:

Future<Product> createProduct(String name) async {
  final response = await http.post(
    Uri.parse('https://example.com/api/products'),
    headers: {
      'Content-Type': 'application/json',
    },
    body: jsonEncode({
      'name': name,
    }),
  );

  if (response.statusCode == 201) {
    return Product.fromJson(
      jsonDecode(response.body),
    );
  }

  throw Exception('Failed to create product');
}

33. GET and POST with a Service Class

For larger applications, it is better to keep networking code in a separate service class.

import 'dart:convert';
import 'package:http/http.dart' as http;

class ApiService {
  final String baseUrl = 'https://example.com/api';

  Future<http.Response> getUsers() {
    return http.get(
      Uri.parse('$baseUrl/users'),
    );
  }

  Future<http.Response> createUser(
    String name,
    String email,
  ) {
    return http.post(
      Uri.parse('$baseUrl/users'),
      headers: {
        'Content-Type': 'application/json',
      },
      body: jsonEncode({
        'name': name,
        'email': email,
      }),
    );
  }
}

This structure keeps API communication separate from presentation widgets.

34. Using http.Client

The http.Client class can be used instead of the top-level request methods. A client can make networking code easier to reuse and test.

final client = http.Client();

try {
  final response = await client.get(
    Uri.parse('https://example.com/api/users'),
  );

  print(response.body);
} finally {
  client.close();
}

For larger applications, an injectable client can make API services easier to test by allowing a test implementation to be supplied.

35. GET Request with FutureBuilder

FutureBuilder can be used to display different UI states while a GET request is running.

Future<String> fetchData() async {
  final response = await http.get(
    Uri.parse('https://example.com/api/message'),
  );

  if (response.statusCode == 200) {
    return response.body;
  }

  throw Exception('Failed to load data');
}

Use it in the UI:

FutureBuilder<String>(
  future: fetchData(),
  builder: (context, snapshot) {
    if (snapshot.connectionState == ConnectionState.waiting) {
      return const CircularProgressIndicator();
    }

    if (snapshot.hasError) {
      return Text('Error: ${snapshot.error}');
    }

    if (snapshot.hasData) {
      return Text(snapshot.data!);
    }

    return const Text('No data available');
  },
)

Important: Avoid creating a new network Future on every widget rebuild. Store or initialize the Future appropriately when necessary.

36. Complete GET Example

import 'dart:convert';
import 'package:http/http.dart' as http;

class Album {
  final int userId;
  final int id;
  final String title;

  Album({
    required this.userId,
    required this.id,
    required this.title,
  });

  factory Album.fromJson(Map<String, dynamic> json) {
    return Album(
      userId: json['userId'],
      id: json['id'],
      title: json['title'],
    );
  }
}

Future<Album> fetchAlbum() async {
  final response = await http.get(
    Uri.parse(
      'https://jsonplaceholder.typicode.com/albums/1',
    ),
    headers: {
      'Accept': 'application/json',
    },
  );

  if (response.statusCode == 200) {
    return Album.fromJson(
      jsonDecode(response.body),
    );
  }

  throw Exception('Failed to load album');
}

37. Complete POST Example

import 'dart:convert';
import 'package:http/http.dart' as http;

class Album {
  final int id;
  final String title;

  Album({
    required this.id,
    required this.title,
  });

  factory Album.fromJson(Map<String, dynamic> json) {
    return Album(
      id: json['id'],
      title: json['title'],
    );
  }
}

Future<Album> createAlbum(String title) async {
  final response = await http.post(
    Uri.parse(
      'https://jsonplaceholder.typicode.com/albums',
    ),
    headers: {
      'Content-Type': 'application/json; charset=UTF-8',
    },
    body: jsonEncode({
      'title': title,
    }),
  );

  if (response.statusCode == 201) {
    return Album.fromJson(
      jsonDecode(response.body),
    );
  }

  throw Exception('Failed to create album');
}

This example demonstrates the complete POST flow: create the endpoint, encode the request body as JSON, send the request, check the response status, decode the returned JSON, and create a Dart model.


38. GET Request Flow

Flutter UI
    ↓
Call fetchData()
    ↓
Create Uri
    ↓
http.get()
    ↓
Server/API
    ↓
HTTP Response
    ↓
Check statusCode
    ↓
Decode JSON
    ↓
Create Model
    ↓
Update UI

39. POST Request Flow

Flutter UI
    ↓
Collect user input
    ↓
Validate input
    ↓
Create request data
    ↓
jsonEncode()
    ↓
http.post()
    ↓
Server/API
    ↓
HTTP Response
    ↓
Check statusCode
    ↓
Decode response
    ↓
Create Model
    ↓
Update UI

40. GET and POST Error Handling

A reliable application should handle both HTTP errors and network exceptions.

GET example:

try {
  final response = await http.get(
    Uri.parse('https://example.com/api/users'),
  );

  if (response.statusCode == 200) {
    print('Success');
  } else {
    print('HTTP Error: ${response.statusCode}');
  }
} catch (e) {
  print('Network Exception: $e');
}

POST example:

try {
  final response = await http.post(
    Uri.parse('https://example.com/api/users'),
    headers: {
      'Content-Type': 'application/json',
    },
    body: jsonEncode({
      'name': 'Rahul',
    }),
  );

  if (response.statusCode == 201) {
    print('Created successfully');
  } else {
    print('HTTP Error: ${response.statusCode}');
  }
} catch (e) {
  print('Network Exception: $e');
}

41. Loading, Success, Error, and Empty States

When sending GET or POST requests, the UI should normally communicate the current state to the user.

State Possible UI Purpose
Loading CircularProgressIndicator Indicate that a request is running
Success Display received or created data Show successful result
Error Error message Explain that the request failed
Empty No-data message Indicate that no records are available
Retry Retry button Allow the user to try the request again

42. GET and POST Authentication

Some APIs require authentication before accepting requests.

For example:

headers: {
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
  'Accept': 'application/json',
}

Authentication can be applied to both GET and POST requests.

final response = await http.get(
  Uri.parse('https://example.com/api/profile'),
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
  },
);

Authentication details depend on the backend API and its security requirements.

43. Sending POST Data from a Form

A common Flutter use case is sending registration or login information collected through a form.

final response = await http.post(
  Uri.parse('https://example.com/api/register'),
  headers: {
    'Content-Type': 'application/json',
  },
  body: jsonEncode({
    'name': nameController.text,
    'email': emailController.text,
    'password': passwordController.text,
  }),
);

Before sending the request, validate the form fields and make sure the API's required fields are available.

Security note: Passwords and other sensitive information should only be sent to a properly secured HTTPS backend according to the backend's authentication design.

44. Avoid Repeated GET Requests

A common mistake is starting a GET request directly inside the build() method of a widget. Flutter may rebuild widgets multiple times, which can result in repeated network calls.

Avoid:

@override
Widget build(BuildContext context) {
  fetchUsers();
  return const Scaffold();
}

Instead, initialize the request at an appropriate lifecycle point or store the Future and reuse it.

Example:

late Future<List<Album>> albumsFuture;

@override
void initState() {
  super.initState();
  albumsFuture = fetchAlbums();
}

45. Separating API Code from UI

For maintainable applications, keep HTTP requests in service, repository, model, or ViewModel layers rather than placing all networking code inside widgets.

lib/
├── models/
│   └── user.dart
├── services/
│   └── api_service.dart
├── repositories/
│   └── user_repository.dart
├── screens/
│   └── users_screen.dart
└── main.dart

A typical responsibility flow can look like this:

UI
 ↓
ViewModel / Controller
 ↓
Repository
 ↓
API Service
 ↓
HTTP Client
 ↓
Backend API

This separation can make the application easier to maintain, reuse, and test.

46. Best Practices for GET and POST Requests

  1. Use the http package for straightforward HTTP communication.
  2. Use async and await for asynchronous requests.
  3. Construct URLs using Uri.
  4. Check HTTP status codes.
  5. Decode JSON using jsonDecode().
  6. Encode JSON request bodies using jsonEncode().
  7. Set the correct Content-Type when sending JSON.
  8. Handle network exceptions with try-catch.
  9. Use timeouts for requests where appropriate.
  10. Show loading, success, empty, and error states in the UI.
  11. Convert API responses into Dart model classes.
  12. Keep networking logic separate from UI code.
  13. Do not expose sensitive secrets unnecessarily in client-side code.
  14. Use injectable clients when networking code needs to be tested.
  15. Avoid making unnecessary repeated network requests.

47. Common Mistakes

  • Forgetting to add the http package.
  • Forgetting Android internet permission when required.
  • Using an incorrect API URL.
  • Not checking statusCode.
  • Calling jsonDecode() on invalid response data.
  • Forgetting jsonEncode() when the API expects JSON.
  • Using the wrong Content-Type.
  • Not handling network exceptions.
  • Not setting a suitable timeout for long-running requests.
  • Making repeated requests inside build().
  • Putting all HTTP logic directly into UI widgets.
  • Not showing a loading indicator during long requests.
  • Not providing an error or retry state.
  • Hard-coding sensitive credentials into the application.

48. Recommended API Development Process

  1. Understand the API documentation.
  2. Identify the endpoint and HTTP method.
  3. Construct the endpoint using Uri.
  4. Determine required headers.
  5. Determine whether a request body is required.
  6. For JSON requests, use jsonEncode().
  7. Send the request asynchronously.
  8. Check the returned status code.
  9. Decode the response using jsonDecode() when appropriate.
  10. Convert the response into Dart models.
  11. Update application state.
  12. Display loading, success, empty, and error states.
  13. Test success and failure scenarios.
  14. Separate API logic from presentation code as the application grows.

49. Practical Mini Project: User Management API

A useful practice project is a simple user management application that demonstrates both GET and POST requests.

GET Features

  • Fetch a list of users from an API.
  • Display a loading indicator.
  • Decode the JSON response.
  • Create a User model.
  • Display users in a ListView.
  • Show an error message if the request fails.
  • Provide a retry button.

POST Features

  • Create a form containing name and email fields.
  • Read values using TextEditingController.
  • Validate the form.
  • Convert form data to JSON.
  • Send it using http.post().
  • Check the response status code.
  • Display a success or error message.
  • Clear the form after successful submission when appropriate.

Suggested Project Structure

lib/
├── models/
│   └── user.dart
├── services/
│   └── api_service.dart
├── screens/
│   ├── users_screen.dart
│   └── add_user_screen.dart
├── widgets/
│   └── user_card.dart
└── main.dart

50. GET and POST Quick Revision

Concept GET POST
Primary purpose Retrieve data Send/create data
Dart method http.get() http.post()
JSON body Usually not required Commonly used
Typical success code 200 201 for resource creation
Common use Fetch users/products Create users/products
Can use headers Yes Yes
Can use authentication Yes Yes

51. Practical Decision Flow

Need to communicate with API?
        ↓
Identify API endpoint
        ↓
Need to retrieve data?
        ├── Yes → GET
        ↓
Need to send/create data?
        └── Yes → POST
        ↓
Construct Uri
        ↓
Add headers if required
        ↓
Add JSON body if required
        ↓
Send request
        ↓
Check status code
        ↓
Handle success/error
        ↓
Decode JSON
        ↓
Create model
        ↓
Update UI

52. Practice Exercise

Create a Flutter application that performs both GET and POST requests.

GET Requirements

  • Fetch a list of users from an API.
  • Display a loading indicator.
  • Decode the JSON response.
  • Create a User model.
  • Display users in a ListView.
  • Show an error message if the request fails.
  • Add a retry option.

POST Requirements

  • Create a form containing name and email fields.
  • Read the values using TextEditingController.
  • Validate the form.
  • Convert the form data to JSON.
  • Send it using http.post().
  • Check the response status code.
  • Display a success or error message.
  • Clear the form after successful submission.

53. Interview Questions

Q1. What is a GET request?

A GET request is an HTTP request generally used to retrieve data from a server.

Q2. What is a POST request?

A POST request is generally used to send data to a server and create or process a resource.

Q3. Which package is commonly used for HTTP requests in Flutter?

The http package is a common choice for HTTP communication in Flutter.

Q4. What does http.get() return?

It returns a Future.

Q5. What does http.post() return?

It returns a Future.

Q6. Why is jsonEncode() used in POST requests?

jsonEncode() converts Dart data into a JSON string that can be sent as the request body when the API expects JSON.

Q7. Why is jsonDecode() used?

jsonDecode() converts JSON response text into Dart data structures such as maps and lists.

Q8. Why should statusCode be checked?

The status code indicates how the server handled the request and helps the application distinguish successful responses from error responses.

Q9. Why are async and await used?

They provide a readable way to work with asynchronous operations such as HTTP requests.

Q10. Why should API calls be separated from UI code?

Separating networking logic improves maintainability, reusability, and testability.

Q11. What is the purpose of the Content-Type header?

It tells the server the media type of the request body, such as JSON.

Q12. What is the difference between query and path parameters?

Query parameters are commonly placed after ? and are useful for filtering, searching, sorting, and pagination. Path parameters are part of the URL path and commonly identify a specific resource.

Q13. Why should HTTP requests not normally be started inside build()?

The build() method can run multiple times, which may cause the same network request to execute repeatedly.

Q14. Why use an API service class?

An API service class separates networking responsibilities from UI code and makes the application easier to maintain and test.

54. Quick Revision

  • GET: Generally used to retrieve data.
  • POST: Generally used to send or create data.
  • http.get(): Sends a GET request.
  • http.post(): Sends a POST request.
  • Uri: Represents the API endpoint.
  • async/await: Handles asynchronous network operations.
  • statusCode: Indicates how the server handled the request.
  • jsonEncode(): Converts Dart data into JSON text.
  • jsonDecode(): Converts JSON text into Dart data.
  • Headers: Provide additional request information.
  • Content-Type: Identifies the format of the request body.
  • Model: Represents API data in a structured Dart object.
  • Service: Keeps networking logic separate from UI.
  • FutureBuilder: Can represent asynchronous Future states in the UI.
  • try-catch: Handles exceptions from asynchronous operations.

55. Learning Outcome

After completing this topic, you should be able to:

  • Understand how Flutter communicates with REST APIs.
  • Explain the difference between GET and POST requests.
  • Add and use the http package.
  • Create API endpoints using Uri.
  • Send GET requests using http.get().
  • Send POST requests using http.post().
  • Work with request headers.
  • Send JSON request bodies.
  • Decode JSON responses.
  • Create Dart models from API responses.
  • Handle loading, success, empty, and error states.
  • Handle HTTP errors and network exceptions.
  • Use authentication headers where required.
  • Separate API logic from UI code.
  • Build practical Flutter applications connected to backend APIs.

56. Official Flutter Resources

57. Learn Flutter with JustAcademy

For structured Flutter training and practical learning, explore the following resources:

JustAcademy Flutter Training Course

Register for Flutter Course Demo


58. Summary

GET and POST requests are fundamental for building API-connected Flutter applications. GET requests are commonly used to retrieve information, while POST requests are commonly used to send data and create resources.

With the http package, Flutter developers can construct a Uri, send an HTTP request, await the response, check the status code, decode JSON, convert the response into Dart models, and update the UI.

A production-ready implementation should also handle loading states, errors, authentication, timeouts, validation, and proper separation between networking and presentation code.

Previous Next
whatsapp